// $Id$
// Implementation of the EventManager class
//
// ml278
// Copyright (C) 2008 Bjørn Øivind Bjørnsen, Aleksander Gjermundsen, Knut Andre Tidemann, Thomas Hansen
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

#include "eventmanager.h"
#include "OgreSingleton.h"

template<> ml278::EventManager* Ogre::Singleton<ml278::EventManager>::ms_Singleton = 0;

namespace ml278 
{
	EventManager::EventManager()
	{
		// reserve space
		mListeners.reserve(NUMBER_OF_TYPES);
		mListeners.resize(NUMBER_OF_TYPES);
		// reserve space and init all elements to 0
		mNumListeners.reserve(NUMBER_OF_TYPES);
		mNumListeners.resize(NUMBER_OF_TYPES, 0);
	}
	
	EventManager::~EventManager()
	{
		mListeners.clear();
	}
	
	bool EventManager::frameStarted(const FrameEvent &evt)
	{
		// call the framestarted-method of all the listeners
		for(unsigned int i = 0; i < NUMBER_OF_TYPES; i++)
		{
			for(unsigned int j = 0; j < mNumListeners.at(i); j++) 
			{
				if(!mListeners.at(i).at(j)->frameStarted(evt))
					return(false);
			}
		}
		return(true);
	}
	
	bool EventManager::frameEnded(const FrameEvent &evt)
	{
		// call the frameended-method of all the listeners
		for(unsigned int i = 0; i < NUMBER_OF_TYPES; i++)
		{
			for(unsigned int j = 0; j < mNumListeners.at(i); j++) 
			{
				if(!mListeners.at(i).at(j)->frameEnded(evt))
					return(false);
			}
		}
		return(true);
	}
	
	void EventManager::addEventListener(EventListener *listener)
	{
		// pushes back the new event in the appropriate vector
		mListeners.at(listener->type).push_back(listener);
		mNumListeners.at(listener->type)++;

	}
	
	void EventManager::addEventListener(EventListener *listener, unsigned int position)
	{
		// adds to the appropriate vector in the specified position;
		vector<EventListener*>::iterator itr = mListeners.at(listener->type).begin();
		for(unsigned int i = 0; i < position; i++) 
		{
			itr++;
		}
		mListeners.at(listener->type).insert(itr, listener);
		mNumListeners.at(listener->type)++;
	}
	
	bool EventManager::removeEventListener(EventListener *listener)
	{
		vector<EventListener*>::iterator itr = mListeners.at(listener->type).begin();
		while(itr != mListeners.at(listener->type).end())
		{
			if(*itr == listener)
			{
				mListeners.at(listener->type).erase(itr);
				mNumListeners.at(listener->type)--;
				return(true);
			}
		}
		return(false);
	}
}
